package com.xiaoyu.beans.factory;

import com.xiaoyu.beans.BeansException;
import com.xiaoyu.beans.PropertyValue;
import com.xiaoyu.beans.PropertyValues;
import com.xiaoyu.beans.factory.config.BeanDefinition;
import com.xiaoyu.beans.factory.config.BeanFactoryPostProcessor;
import com.xiaoyu.core.io.DefaultResourceLoader;
import com.xiaoyu.core.io.Resource;

import java.io.IOException;
import java.util.Properties;

public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {
    public static final String PLACEHOLDER_PREFIX = "${";
    public static final String PLACEHOLDER_SUFFIX = "}";
    private String location;

    public void setLocation(String location) {
        this.location = location;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 加载属性文件
        Properties properties = loadProperties();

        // 替换占位符
        processProperties(beanFactory, properties);
    }

    /**
     * 替换占位符
     * @param beanFactory
     * @param properties
     */
    private void processProperties(ConfigurableListableBeanFactory beanFactory, Properties properties) {
        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
            resolvePropertyValues(beanDefinition, properties);
        }
    }

    /**
     * 替换占位符实现
     * @param beanDefinition
     * @param properties
     */
    private void resolvePropertyValues(BeanDefinition beanDefinition, Properties properties) {
        PropertyValues propertyValues = beanDefinition.getPropertyValues();
        for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
            Object value = propertyValue.getValue();
            if (value instanceof String) {
                String strVal = (String) value;
                StringBuffer strBuf = new StringBuffer(strVal);// 确保线程安全
                int prefixIndex = strVal.indexOf(PLACEHOLDER_PREFIX);
                int suffixIndex = strVal.indexOf(PLACEHOLDER_SUFFIX);
                if (prefixIndex != -1 && suffixIndex != -1 && prefixIndex < suffixIndex) {
                    String propKey = strVal.substring(prefixIndex + PLACEHOLDER_PREFIX.length(), suffixIndex);
                    String propVal = properties.getProperty(propKey);
                    strBuf.replace(prefixIndex, suffixIndex + PLACEHOLDER_SUFFIX.length(), propVal);
                    propertyValues.addPropertyValue(new PropertyValue(propertyValue.getName(), strBuf.toString()));
                }
            }
        }
    }

    /**
     * 加载属性
     * @return
     */
    private Properties loadProperties() {
        try {
            DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);
            Properties properties = new Properties();
            properties.load(resource.getInputStream());
            return properties;
        } catch (IOException e) {
            throw new BeansException("Could not load properties!", e);
        }
    }
}
